<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
<style>
    body {
        margin: 0;
        background: black;
    }
</style>
</head>
<body>
<div id="sketch"></div>
    <script src="../../public/script/kokomi.umd.js"></script>
    <script src="../../public/script/three.min.js"></script>
<script>
    class Sketch extends kokomi.Base {
        create() {
            this.camera.position.set(0, 0, 5);
            new kokomi.OrbitControls(this);

            const geometry = new THREE.SphereGeometry(2, 64, 64);
            // const geometry = new THREE.PlaneGeometry(4, 4);

const envmap = new THREE.CubeTextureLoader().load([
  "https://s2.loli.net/2022/09/29/X8TDZROlUo6uAyG.png",
  "https://s2.loli.net/2022/09/29/KYEJ9ylQNIe6h4R.png",
  "https://s2.loli.net/2022/09/29/GqseLg6tWoluDzV.png",
  "https://s2.loli.net/2022/09/29/LUk8P21MJG6AtNF.png",
  "https://s2.loli.net/2022/09/29/4BO1JHoM3phFCb7.png",
  "https://s2.loli.net/2022/09/29/5NvAxfCVqlKFRZU.png",
]);

            const material = new THREE.ShaderMaterial({
                uniforms: {
                    iChannel0: {
                        value: envmap,
                    },
                },
                vertexShader: /* glsl */ `
uniform float iTime;
uniform vec3 iResolution;
uniform vec4 iMouse;

varying vec2 vUv;
varying vec3 vNormal;
varying vec3 vWorldPosition;

void main(){
    vec3 p=position;
    gl_Position=projectionMatrix*modelViewMatrix*vec4(p,1.);
    
    vUv=uv;
    vNormal = normal;
    vWorldPosition = vec3(modelViewMatrix * vec4(p, 1.));
}
  `,
                fragmentShader: /* glsl */ `
uniform float iTime;
uniform vec3 iResolution;
uniform vec4 iMouse;
uniform samplerCube iChannel0;

varying vec2 vUv;
varying vec3 vNormal;
varying vec3 vWorldPosition;

float fresnel(float bias,float scale,float power,vec3 I,vec3 N)
{
    return bias+scale*pow(1.-dot(I,N),power);
}


void main(){
    vec2 uv=vUv;

    vec3 col = vec3(0.);
    vec3 objectColor = vec3(1.);
    vec3 lightColor = vec3(.875, .286, .333);

    // 环境光
    float ambIntensity = .2;
    vec3 ambient = lightColor * ambIntensity;
    col += ambient * objectColor;

    // diffuse
    vec3 lightPos = vec3(1., 2., 1.);
    vec3 lightDir = normalize(lightPos - vWorldPosition);
    float diff = dot(vNormal, lightDir);
    diff = max(diff, 0.);

    vec3 diffuse = lightColor * diff;
    col += diffuse * objectColor;

    // 高光
    vec3 reflectDir = reflect(-lightDir, vNormal);
    vec3 viewDir = normalize(cameraPosition - vWorldPosition);
    //float spec = dot(viewDir, reflectDir);
    vec3 halfVec = normalize(viewDir + lightDir);
    float spec = dot(vNormal, halfVec);
    spec = max(spec, 0.);

    // 反光度
    float shininess = 32.;
    spec = pow(spec, shininess);

    vec3 specular = lightColor * spec;
    col += specular * objectColor;

    // IBL
    float iblIntensity = .2;
    vec3 iblCoord = normalize(reflect(-viewDir, vNormal));
    vec3 ibl = texture(iChannel0, iblCoord).xyz;
    vec3 iblLight = ibl * iblIntensity;
    col += iblLight * objectColor;

    // fresnel
    vec3 fresColor = vec3(1.);
    float fresIntensity = .6;
    float fres = fresnel(0., 1., 5., viewDir, vNormal);
    vec3 fresLight = fresColor * fresIntensity * fres;
    col += fresLight * objectColor;

    gl_FragColor=vec4(col, 1.);
}
  `,
            });
            const mesh = new THREE.Mesh(geometry, material);
            this.scene.add(mesh);

            const uj = new kokomi.UniformInjector(this);
            material.uniforms = {
                ...material.uniforms,
                ...uj.shadertoyUniforms,
            };
            this.update(() => {
                uj.injectShadertoyUniforms(material.uniforms);
            });
        }
    }

    const sketch = new Sketch("#sketch");
    sketch.create();
</script>
</body>
</html>